package com.tieshan.smartwindow.other

import android.app.*
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.os.Build
import android.os.Process
import android.util.Log
import com.blankj.utilcode.BuildConfig
import com.tieshan.smartwindow.app.AppApplication.Companion.app
import java.io.*
import java.lang.Exception
import java.lang.StringBuilder
import java.text.DecimalFormat
import java.text.SimpleDateFormat
import java.util.*

/**
 *    author : Android 轮子哥
 *    github : https://github.com/getActivity/AndroidProject-Kotlin
 *    time   : 2020/02/03
 *    desc   : Crash 处理类
 */
class CrashHandler private constructor(private val application: Application) :
    Thread.UncaughtExceptionHandler {

    companion object {

        /** Crash 文件名 */
        private const val CRASH_FILE_NAME: String = "crash_file"

        /** Crash 时间记录 */
        private const val KEY_CRASH_TIME: String = "key_crash_time"

        /**
         * 注册 Crash 监听
         */
        fun register(application: Application) {
            Thread.setDefaultUncaughtExceptionHandler(CrashHandler(application))
        }
    }

    private val nextHandler: Thread.UncaughtExceptionHandler? = Thread.getDefaultUncaughtExceptionHandler()

    init {
        if ((javaClass.name == nextHandler?.javaClass?.name)) {
            // 请不要重复注册 Crash 监听
            throw IllegalStateException("are you ok?")
        }
    }

    @Suppress("ApplySharedPref")
    override fun uncaughtException(thread: Thread, throwable: Throwable) {
        initErrorText(throwable)
//        // 不去触发系统的崩溃处理（com.android.internal.os.RuntimeInit$KillApplicationHandler）
//        if (nextHandler != null && !nextHandler.javaClass.name
//                .startsWith("com.android.internal.os")) {
//            nextHandler.uncaughtException(thread, throwable)
//        }

        // 杀死进程（这个事应该是系统干的，但是它会多弹出一个崩溃对话框，所以需要我们自己手动杀死进程）
        Process.killProcess(Process.myPid())
        System.exit(10)
    }


    private fun initErrorText(throwable: Throwable) {
        val stringWriter = StringWriter()
        val printWriter = PrintWriter(stringWriter)
        throwable.printStackTrace(printWriter)
        val cause = throwable.cause
        cause?.printStackTrace(printWriter)
        val mStackTrace = stringWriter.toString()
//        //todo  暂时屏蔽service日志错误，因为service在程序崩溃以后没有销毁，重启activity会报异常，暂时没有找到解决方法
//        if (mStackTrace.contains("com.tieshan.smartwindow.service.PisService")) {
//            return
//        }
        val builder = StringBuilder()
        builder.append("\n安卓版本：\t").append(Build.VERSION.RELEASE)
            .append("\nAPI版本：\t").append(Build.VERSION.SDK_INT)
            .append("\nCPU：\t").append(Build.SUPPORTED_ABIS[0])
        builder.append("\nApp版本名称：\t").append(BuildConfig.VERSION_NAME)
            .append("\nApp版本号：\t").append(BuildConfig.VERSION_CODE)
        try {
            val dateFormat = SimpleDateFormat("MM-dd HH:mm", Locale.getDefault())
            val packageInfo: PackageInfo = app!!.getPackageManager()
                .getPackageInfo(
                    app!!.getPackageName(),
                    PackageManager.GET_PERMISSIONS
                )
            builder.append("\n第一次下载时间：\t")
                .append(dateFormat.format(Date(packageInfo.firstInstallTime)))
                .append("\n上次下载时间：\t").append(dateFormat.format(Date(packageInfo.lastUpdateTime)))
                .append("\n错误时间：\t").append(dateFormat.format(Date()))
            builder.append("\n错误信息：\t").append(mStackTrace)
        } catch (e: PackageManager.NameNotFoundException) {
            builder.append("\n包信息：\t").append(e)
        }
        writerToFile(builder.toString())
    }

    private fun writerToFile(errorinfo: String) {
        try {
            FileUtil.writeFile(FileConfig.ErrorLogPath, "Crash", errorinfo, false)
        } catch (e: Exception) {
            Log.e("TAG", "writerToFile - " + e.message)
        }
    }
}